/*
 * $URL: https://dnsprobe.googlecode.com/svn/trunk/dnsprobe/src/dnsprobe/resolver/Statistics.java $
 * 
 * Copyright (c) 2009, Anonymous
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Anonymous nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY ANONYMOUS ''AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL ANONYMOUS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

package dnsprobe.data;


/**
 * Statistiken
 * 
 * @author BerndBernhardson
 * @author anon004
 * @author snoop
 * @version $Id: Statistics.java 141 2009-07-02 11:46:35Z anonymousRepo@hellokitty.com $
 *
 */
public class Statistics
{
	private long startTime;
	private long stopTime;
	
	private int progressResolveCurrent;
	private int progressResolveMax;
	
	private int progressCompareCurrent;
	private int progressCompareMax;
	
	private int equal;
	private int different;
	private int searchSite;
	
	private int openFound;
	private int openNotFound;
	
	private int userFound;
	private int userNotFound;
	
	/**
	 * Konstruktor
	 */
	public Statistics()
	{
		reset();
	}
	
	/**
	 * Setzt alle Zaehler zurueck
	 */
	public synchronized void reset()
	{
		// damit isDone() false liefert
		reset(1, 1);
	}
	
	/**
	 * Setzt alle Zaehler auf 0 und die Status-Maximalwerte auf 
	 * die angegebenen Parameter.
	 * 
	 * @param resolveMax 100%-Wert fuer den Aufloesungsprozess
	 * @param compareMax 100%-Wert fuer den Vergleichsprozess
	 */
	public synchronized void reset(final int resolveMax, final int compareMax)
	{
		startTime = 0L;
		stopTime  = 0L;
		
		progressResolveCurrent = 0;
		progressResolveMax     = resolveMax;
		
		progressCompareCurrent = 0;
		progressCompareMax     = compareMax;
		
		equal      = 0;
		different  = 0;
		searchSite = 0;
		
		openFound    = 0;
		openNotFound = 0;
		
		userFound    = 0;
		userNotFound = 0;
	}
	
	/**
	 * Startet die Zeitmessung
	 */
	public void resolvingStarted()
	{
		this.startTime = System.currentTimeMillis();
	}
	
	/**
	 * Stoppt die Zeitmessung
	 */
	public void resolvingStopped()
	{
		this.stopTime = System.currentTimeMillis();
	}
	
	/**
	 * Liefert die Zeitspanne zwischen startNow() und stopNow() als Timestamp
	 * 
	 * @return Die Zeitspanne als Timestamp
	 */
	public long getDuration()
	{
		final long result;
		
		result = stopTime - startTime;
		
		return result;
	}
	
	/**
	 * Sagt ob alle Hostnamen aufgeloest und alle Ergebnisse verglichen wurden
	 * 
	 * @return Ob alle Hostnamen aufgeloest und alle Ergebnisse verglichen wurden
	 */
	public boolean isDone()
	{
		return (this.progressCompareCurrent == this.progressCompareMax);
	}
	
	/**
	 * Erhoeht den Aufloeseprozess um eins
	 */
	public synchronized void incResolveProgress()
	{
		progressResolveCurrent++;
	}
	
	/**
	 * Liefert die Anzahl der Aufloeseanfragen
	 * 
	 * @return Die Anzahl der Aufloeseanfragen
	 */
	public synchronized int getResolveProgress()
	{
		return progressResolveCurrent;
	}
	
	/**
	 * Liefert den aktuellen Aufloesungsfortschritt in Prozent als float
	 * 
	 * @return Den aktuellen Aufloesungsfortschritt
	 */
	public synchronized float getResolveProgressPercent()
	{
		return (float)(((float)getResolveProgress() / (float)progressResolveMax) * 100.0f);
	}
	
	/**
	 * Liefert den aktuellen Aufloesungsfortschritt in Prozent als Ganzzahl
	 * 0% = 0, 100% = 100
	 * 
	 * @return Den aktuellen Aufloesungsfortschritt
	 */
	public synchronized int getResolveProgressPercentInt()
	{
		return Math.round(getResolveProgressPercent());
	}
	
	/**
	 * Liefert den aktuellen Aufloesungsfortschritt in Prozent als Kommazahl
	 * 0.0% = 0, 100.0% = 100
	 * 
	 * @return Den aktuellen Aufloesungsfortschritt
	 */
	public synchronized float getResolveProgressPercentFloat()
	{
		return (float)(((int)(getResolveProgressPercent() * 100)) / 100.0f);
	}
	
	/**
	 * Erhoeht die Anzahl der Aufloeseanfragen um eins
	 */
	public synchronized void incCompareProgress()
	{
		progressCompareCurrent++;
	}
	
	/**
	 * Liefert die Anzahl der bisher verglichenen  Hosts
	 * 
	 * @return Die Anzahl der bisher verglichenen  Hosts
	 */
	public synchronized int getCompareProgress()
	{
		return progressCompareCurrent;
	}
	
	/**
	 * Liefert den aktuellen Vergleichsstatus in Prozent als float
	 * 
	 * @return Den aktuellen Vergleichsstatus
	 */
	public synchronized float getCompareProgressPercent()
	{
		return (float)(((float)getCompareProgress() / (float)progressCompareMax) * 100.0f);
	}
	
	/**
	 * Liefert den aktuellen Vergleichsstatus in Prozent als Ganzzahl
	 * 0% = 0, 100% = 100
	 * 
	 * @return Den aktuellen Vergleichsstatus
	 */
	public synchronized int getCompareProgressPercentInt()
	{
		return Math.round(getCompareProgressPercent());
	}
	
	
	/**
	 * Liefert den aktuellen Aufloesungsfortschritt in Prozent als Kommazahl
	 * 0.0% = 0, 100.0% = 100
	 * 
	 * @return Den aktuellen Aufloesungsfortschritt
	 */
	public synchronized float getCompareProgressPercentFloat()
	{
		return (float)(((int)(getResolveProgressPercent() * 100)) / 100.0f);
	}
	
	/**
	 * Liefert die Gesamtzahl der Nameserveranfragen
	 * 
	 * @return Die Gesamtzahl der Nameserveranfragen
	 */
	public synchronized int getTotalLookups()
	{
		return getOpenFound() + getOpenNotFound() + getUserFound() + getUserNotFound();
	}

	/**
	 * Liefert die Anzahl der im ungefilterten Nameserver existierenden Hosts
	 * 
	 * @return Die Anzahl der im ungefilterten Nameserver existierenden Hosts
	 */
	public synchronized int getOpenFound()
	{
		return this.openFound;
	}

	/**
	 * Erhoeht die Anzahl der im ungefilterten Nameserver existierenden Hosts um eins
	 */
	public synchronized void incOpenFound()
	{
		this.openFound++;
	}

	/**
	 * Liefert die Anzahl der im ungefilterten Nameserver nicht-gefundenen Hosts
	 * 
	 * @return Die Anzahl der im ungefilterten Nameserver nicht-gefundenen Hosts
	 */
	public synchronized int getOpenNotFound()
	{
		return this.openNotFound;
	}

	/**
	 * Erhoeht die Anzahl der im ungefilterten Nameserver nicht-gefundenen Hosts um eins
	 */
	public synchronized void incOpenNotFound()
	{
		this.openNotFound++;
	}

	/**
	 * Liefert die Anzahl der im gefilterten Nameserver gefundenen Hosts
	 * 
	 * @return Die Anzahl der im gefilterten Nameserver gefundenen Hosts
	 */
	public synchronized int getUserFound()
	{
		return this.userFound;
	}

	/**
	 * Erhoeht die Anzahl der im gefilterten Nameserver gefundenen Hosts um eins
	 */
	public synchronized void incUserFound()
	{
		this.userFound++;
	}

	/**
	 * Liefert die Anzahl der im gefilterten Nameserver nicht-gefundenen Hosts
	 * 
	 * @return Die Anzahl der im gefilterten Nameserver nicht-gefundenen Hosts
	 */
	public synchronized int getUserNotFound()
	{
		return this.userNotFound;
	}

	/**
	 * Erhoeht die Anzahl der im gefilterten Nameserver nicht-gefundenen Hosts um eins
	 */
	public synchronized void incUserNotFound()
	{
		this.userNotFound++;
	}

	/**
	 * Liefert die Anzahl der Hosts mit gleichen Ergebnissen
	 * 
	 * @return Die Anzahl der Hosts mit gleichen Ergebnissen
	 */
	public synchronized int getEqual()
	{
		return this.equal;
	}

	/**
	 * Erhoeht die Anzahl der Hosts mit gleichen Ergebnissen um eins
	 */
	public synchronized void incEqual()
	{
		this.equal++;
	}

	/**
	 * Liefert die Anzahl der Hosts mit unterschiedlichen Ergebnissen
	 * 
	 * @return Die Anzahl der Hosts mit unterschiedlichen Ergebnissen
	 */
	public synchronized int getDifferent()
	{
		return this.different;
	}

	/**
	 * Erhoeht die Anzahl der Hosts mit unterschiedlichen Ergebnissen um eins
	 */
	public synchronized void incDifferent()
	{
		this.different++;
	}

	/**
	 * Liefert die Anzahl der Hosts die auf eine Suchseite laufen
	 * 
	 * @return Die Anzahl der Hosts die auf eine Suchseite laufen
	 */
	public synchronized int getSearchSite()
	{
		return this.searchSite;
	}

	/**
	 * Erhoeht die Anzahl der Hosts die auf eine Suchseite laufen um eins
	 */
	public synchronized void incSearchSite()
	{
		this.searchSite++;
	}
	
	/**
	 * Liefert die Zeitdauer als String im format HH:MM:SS
	 * 
	 * @return String Die Dauer als String
	 */
	public String getDurationAsString()
	{
		final long duration;
		final long seconds;
		final long minutes;
		final long hours;
		
		final String result;
		
		duration = getDuration();
		seconds  = duration / 1000;
		minutes  = seconds  / 60;
		hours    = minutes  / 60;
		
		result = String.format(
			"%02d:%02d:%02d",
			hours,
			minutes - (hours * 60),
			seconds - ((minutes - (hours * 60)) * 60)
		);
		
		return result;
	}
	
	/**
	 * Liefert eine Zusammenfassung als String
	 */
	@Override
	public String toString()
	{
		final StringBuilder result;
		
		result = new StringBuilder();
		
		result.append("[");
		
		result.append("ProgressResolve=");
		result.append(getResolveProgressPercent());
		result.append("%");
		result.append(";");
		
		result.append("ProgressCompare=");
		result.append(getCompareProgressPercent());
		result.append("%");
		result.append(";");
		
		result.append("OpenFound=");
		result.append(getOpenFound());
		result.append(";");
		
		result.append("OpenNotFound=");
		result.append(getOpenNotFound());
		result.append(";");
		
		result.append("UserFound=");
		result.append(getUserFound());
		result.append(";");
		
		result.append("UserNotFound=");
		result.append(getUserNotFound());
		result.append(";");
		
		result.append("Equal=");
		result.append(getEqual());
		result.append(";");
		
		result.append("Different=");
		result.append(getDifferent());
		result.append(";");
		
		result.append("SearchSite=");
		result.append(getSearchSite());
		
		result.append("]");
		
		return result.toString();
	}
}
